package com.itheima.d0_feedback;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/*
在使用Synchronize同步代码块时，他的作用是保证语句体里的语句只被一个线程所访问使用，我们通常使用this去代表对象锁，那么问题来了，
如果我是不同对象的不同进程的话，拿银行取钱案例举例，我再创建一个新账户对象，这两个账户对象同时去取钱，
他们应该是要同时访问使用到被同步代码块所包裹的语句体，那么对象锁的效果岂不是消失了，
两个对象的不同线程在同一时间访问到了同步代码块的语句体，怎么去理解这个对象锁呢？

线程安全出现的原因？
    多个线程访问同一个资源，进行修改操作。一定要保证资源使用时的互斥性。

到底是锁住了一条线程还是this同一个对象的不同线程里的一条线程呢？
    当同步代码块包裹其访问资源的代码时，只要多个线程使用的是相同锁对象，那么就会互斥访问。

    synchronized("锁"){
        资源访问1
        资源访问2
        资源访问3
    }

    synchronized("锁"){
        资源访问4
        资源访问5
        资源访问6
    }


    老师，学了这么多天，不知道哪些是工作必会，哪些仅作为了解。后面本章节结束最后一天，可以花几个小时时间带我们捋一遍面向对象进阶的重点知识点吗？
    只要是语法必须要掌握，面向对象（继承，多态，接口，抽象类，枚举，泛型，Lambda .....）
    JavaSE：
        1、工具软件的软件
        2、语法
        3、API(String,StringBuilder,Date,SimpleDateFormat .....)
        4、设计（算法，数据结构，设计模式，编程模式）


synchronized（）的唯一对象，一般是使用共享资源。道理都懂，就是往回追溯的过程不是很明白，能举例说明吗？
    就看多个线程处理的资源是什么，用这个资源对象做锁对象就可以了。
    如果操作资源的业务逻辑在资源类型的内部，建议使用this当做锁。


wait时间没到被其他线程唤醒，并得到锁对象，是随机选状态的线程并唤醒，没有先来后到吗？
    唤醒的方法：
    notify     唤醒一个（任意的）
    notifyAll  唤醒所有


1. 包子案例, 为啥拿plate做锁对象,除了他是共享资源外, 还有什么原因吗?
    没有
2.我还有个疑问, 共享资源指的是plate这个盘子? 还是同步代码块里面的所有代码都是共享资源?
    就是这个plate集合对象（厨师线程放包子到plate里面去，吃货线程从plate中拿包子）
    被同步代码块包括的代码是操作资源的逻辑代码。要求多个线程要互斥执行。

3. public int hashCode() {return Objects.hash(id, date, receiver, items, remarks);}
   忘了重写hashcode方法, 里面的代表的含义了.

   hashCode没有重写前，一个对象的哈希值是有底层JVM根据地址生成的。
   重写后对象的哈希值由对象中的属性值一起决定了。

处理Callable任务时，线程未执行完毕，未返回结果，此时调用future的get方法还能得到结果吗？
是返回null值，还是调用Callable任务的线程阻塞等待结果？如果是阻塞的话跟单线程没有区别了吧。
不行，会阻塞等待。
和单线程有区别，不同的任务不同的线程去处理。
请看下面的点外卖例子。


 */
public class Demo01 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //主线程
        System.out.println("上第一节课");
        FutureTask<String> f = new FutureTask<>(new OrderLunch());
        new Thread(f).start();//点餐
        System.out.println("上第二节课");
        System.out.println("上第三节课");
        System.out.println("上第四节课");
        String lunch = f.get();
        System.out.println("今天中午吃" + lunch);

    }
}

class OrderLunch implements Callable<String>{
    @Override
    public String call() throws Exception {
        Thread.sleep(2000);
        return "黄焖鸡";
    }
}